<?php

import("data.db.DbAbstractTable");
import("data.db.DbAbstractForeign");
import("data.db.DbFactory");
import("data.logic.catalogue.Node");
import("data.logic.catalogue.Catalogue");

class DbNode extends DbAbstractTable {
	
	public $className = "data.logic.catalogue.Node";
	const CLASS_NAME = "data.logic.catalogue.Node";
	
	const TB_TABLENAME	= "pd_catalog_node";
	const TB_I			= 'catn';
	
	const TB_NAME		= 'catn_name';

	
	public static function _get_TABLENAME() {return self::TB_TABLENAME;}
	public static function _get_ID() {return self::TB_I."_id";}
	public static function _get_SUFFIX() {return self::TB_I;}
	

	function forwardForeignCollection() {
		return array("Catalogue"=>"data.logic.catalogue.Catalogue");
	}
	function backwardForeignCollection() {
		return array("Link"=>"data.logic.catalogue.NodeLink");
	}
	
	// properties
	public $name;
	public $parentNode;
	
	public function __construct($noinit=false) {
		parent::__construct($noinit);
	}
	
	function setName($name) {
		if(!(strpos($name,":")===false)) {
			throw new Exception("Node name cannot contein any of following characters: \ / :");
		}
		$this->name = $name;
	}
	function getName() {return $this->name;}
	
	function getCaption() {
		$lingvo = Bundle::findByKey($this->name, $this->locale->getId());
		if ($lingvo) return $lingvo->getValue();
		return $this->name;
	}
	
	function setCatalogue(&$cat) {
		$this->forwardForeigns["Catalogue"]->setForeign($cat);
	}
	function &getCatalogue() {
		return $this->forwardForeigns["Catalogue"]->getForeign();
	}
	
	function setLinks($links) {
		$this->backwardForeigns["Link"]->setList($links);
	}
	function &getLinks() {
		return $this->backwardForeigns["Link"]->getList();
	}
	
	// restore
	function fillEntity($arrResult) {
		parent::fillEntity($arrResult);
		$this->setName($arrResult[self::TB_NAME]);
		
		//Forward Foreigns
		//$this->initForeign($arrResult, 'data.logic.catalogue.Catalogue');
	}
	
	//store
	function fillFields() {
		parent::fillFields();
		$this->fildsForStore[self::TB_NAME] = "'".$this->getName()."'";
		
		//$this->fildsAddForeign('data.logic.catalogue.Catalogue');
	}
	
	
	/**
	* @return Node
	* @param Node $node
	* @desc Add child Node to current Node
	*/
	function addNode(&$node) {
		$cat = &$this->getCatalogue();
		if(DbNode::findByName($node->getName(),$cat->getId())!=null) {
			throw new Exception("Node with name '".$node->getName()."' is already exists");
		}
		
		$node->setCatalogue(&$cat);
		$node->store();
		
		$link = new NodeLink();
		$link->setParentNode($this);
		$link->setChildNode($node);
		$link->setCatalogue(&$cat);
		$link->setType(NodeLink::TYPE_MAIN);
		$link->store();
		
		$node->setLinks(array($link));
		return $node;
	}
	
	/**
	* @return Node
	* @desc Retrive parent Nodes
	*/
	function getParents() {
		$listObjs = DbAbstractTable::__selectObjects(
			"select * from pd_catalog_node where ".self::_get_ID()." in (select catl_id_parent from pd_catalog_link where catl_id_catn='".$this->getId()."')",
			"data.logic.catalogue.Node");
		return $listObjs;
	}
	
	function getParent() {
		$listObjs = DbAbstractTable::__selectObjects(
			"select * from pd_catalog_node where ".self::_get_ID()." in (select catl_id_parent from pd_catalog_link where catl_id_catn='".$this->getId()."' and catl_type='main')",
			"data.logic.catalogue.Node");
		if (is_array($listObjs) && count($listObjs)>0) return $listObjs[0];
		return null;
	}
	
	/**
	* @return Array
	* @desc Retrive all child Nodes
	*/
	function getChildren() {
		$listObjs = DbAbstractTable::__selectObjects(
			"select * from pd_catalog_node where ".self::_get_ID()." in (select ".DbAbstractTable::_get_FOREIGN("data.logic.catalogue.NodeLink", "data.logic.catalogue.Node")." from pd_catalog_link where catl_id_parent='".$this->getId()."')",
			"data.logic.catalogue.Node");
		return $listObjs;
	}
	
	function getNodeByName($name) {
		return self::findByName($name, $this->forwardForeigns["Catalogue"]->getForeignId());
	}
	
	//static
	function findByName($name, $catalogueId) {
		return parent::__selectByCriteria(
			self::TB_NAME."='".$name."' and ".
			DbAbstractTable::_get_FOREIGN("data.logic.catalogue.Node", "data.logic.catalogue.Catalogue")."='$catalogueId'",
			'data.logic.catalogue.Node');
	}
	
	// same for all classes
    public static function findAll() {
    	return parent::findAll(self::CLASS_NAME);
    }
    public static function findById($id) {
    	return parent::findById($id, self::CLASS_NAME);
    }
}
?>